package com.demo.util;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.demo.exception.BusinessException;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * AlibabaEasyExcel
 */
@Slf4j
public class ExcelUtil {

    public static void exportCsv(List list, Class head, String sheetName, OutputStream os) {
        ExcelWriterBuilder excelBuilder = EasyExcelFactory.write(os).excelType(ExcelTypeEnum.CSV).head(head);
        ExcelWriterSheetBuilder builder = excelBuilder.sheet(sheetName);
        builder.doWrite(list);

    }

    public static void exportCsv(List<List<String>> head, List<List<String>> lineList, String sheetName,
        OutputStream os) {
        ExcelWriterBuilder excelBuilder = EasyExcelFactory.write(os).excelType(ExcelTypeEnum.CSV).head(head);
        ExcelWriterSheetBuilder builder = excelBuilder.sheet(sheetName);
        builder.doWrite(lineList);

    }

    public static void exportExcel(List list, Class head, String sheetName, OutputStream os) throws Exception {
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 字体居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setWrapped(true);// 自动换行
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
            new HorizontalCellStyleStrategy(new WriteCellStyle(), contentWriteCellStyle);
        ExcelWriterBuilder excelBuilder =
            EasyExcelFactory.write(os).registerWriteHandler(horizontalCellStyleStrategy).head(head);
        ExcelWriterSheetBuilder builder = excelBuilder.sheet(sheetName);
        builder.doWrite(list);
    }

    public static void exportExcel(List<List<String>> head, List<List<String>> lineList, String sheetName,
        OutputStream os, WriteHandler... writeHandler) throws Exception {
        // new LongestMatchColumnWidthStyleStrategy()
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 字体居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.RIGHT);
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        // contentWriteCellStyle.setWrapped(true);// 自动换行
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
            new HorizontalCellStyleStrategy(new WriteCellStyle(), contentWriteCellStyle);
        ExcelWriterBuilder excelBuilder =
            EasyExcelFactory.write(os).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .registerWriteHandler(horizontalCellStyleStrategy).head(head);
        if (writeHandler != null && writeHandler.length > 0) {
            for (WriteHandler h : writeHandler) {
                excelBuilder.registerWriteHandler(h);
            }
        }
        ExcelWriterSheetBuilder builder = excelBuilder.sheet(sheetName);
        builder.doWrite(lineList);
    }

    public static List<List<String>> getSimpleHead(List<List<String>> list, String... heads) {
        List<String> hl = null;
        for (String head : heads) {
            hl = new ArrayList<>();
            hl.add(head);
            list.add(hl);
        }
        return list;
    }

    public static List<List<String>> getSimpleHead(String... heads) {
        List<List<String>> list = new ArrayList<>();
        List<String> hl = null;
        for (String head : heads) {
            hl = new ArrayList<>();
            hl.add(head);
            list.add(hl);
        }
        return list;
    }

    public static void setComplexHead(List<List<String>> list, String... h2) {
        List<String> hl = new ArrayList<>();
        Collections.addAll(hl, Arrays.copyOf(h2, h2.length));
        // for (String head : h2) {
        // hl.add(head);
        // }

        list.add(hl);
    }

    public static OutputStream getOutputStream(String fileName, HttpServletResponse response, String fileEnd) {
        String filePath = fileName + "." + fileEnd;
        try {
            response.resetBuffer();// reset 会清空header和statusCode导致复杂的CORS设置请求头被清空导致Ajax解析失败
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            String foname = null;
            foname = URLEncoder.encode(filePath, "UTF-8").replace("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename=" + foname + ";filename*=utf-8''" + foname);
            return response.getOutputStream();
        } catch (IOException e) {
            throw new BusinessException("创建文件失败!");
        }
    }

    public static OutputStream getOutputStream(String fileName, HttpServletResponse response) {
        return getOutputStream(fileName, response, "xlsx");
    }

}
